首先可以明确一个问题,其实我们不需要求两个落点之间的距离,而只要求上图中两条红色竖线之间的距离就好了,原因是不管往左上跳,还是往有上跳,这两种跳法左右对称,所以每一次跳动的距离,其实正比于两个底座的中心的 x 坐标的距离,也就是上图两条竖直红线的距离。
假设第一条红色竖线为跳之前位置,第二条竖线为下一个底座中心线。第一条竖线的 x 坐标,可以通过从上到下从左到右扫描图片每一个像素,直到找到了颜色和跳动的棋子颜色相同的颜色 (一种比较深的紫色)。然后就可以找到第一条红线的 x 坐标了。第二条竖线,可以在首次扫描到和背景颜色不一致的颜色时,此时应该就是下一个底座的最靠上的像素,并且由于底座要么是圆柱形要么是长方体,所以这个像素也就是左右方向上是居中的,也就是我们要找的第 2 条竖线的位置。
from PIL import Image import os import time import random
def is_ball_color(r, g, b): # 判断是否是棋子顶部小球的颜色 if r < 50 or r > 70: return False if g < 50 or g > 70: return False if b < 50 or b > 70: return False return True
def is_base_color(r, g, b): # 判断是否是棋子底座的颜色 if r < 50 or r > 70: return False if g < 50 or g > 70: return False if b < 90 or b > 100: return False return True
while True: os.system('adb shell /system/bin/screencap -p /sdcard/screenshot.png') os.system('adb pull /sdcard/screenshot.png .') img = Image.open('screenshot.png') w = img.size[0] h = img.size[1] if w == 0 or h == 0: print('w, h:', w, h) break # print img.getpixel((310, 933)) # print img.getpixel((311, 933)) # 首先是扫描来找棋子 base_x = base_y = 0 for y in range(400, h): # y 坐标从 400 开始,避免扫描到图片顶部的按钮 x = 0 for x in range(0, w): px = img.getpixel((x, y)) if is_ball_color(px[0], px[1], px[2]): px = img.getpixel((x, y + 192)) if is_base_color(px[0], px[1], px[2]): break if x < w - 1: base_x = x base_y = y break base_y += 192 if base_x == 0: print('base_x == 0') break print('base:', base_x, base_y) bg_px = img.getpixel((0, 400))
# 然后是扫描来找下一个底座的位置 dest_x = dest_y = 0 for y in range(400, h): x = 0 for x in range(0, w): if x % 50 == 0 and x > 0: px = img.getpixel((x - 50, y)) if is_similar_color(bg_px[0 : 3], px[0 : 3]): bg_px = px px = img.getpixel((x, y)) if abs(px[0] - bg_px[0]) > 20 or abs(px[1] - bg_px[1]) > 20 or abs(px[2] - bg_px[2]) > 20: if abs(x - base_x) > 100: y += 10 left = right = x while not is_similar_color(bg_px[0 : 3], img.getpixel((left, y))[0 : 3]): left -= 1 while not is_similar_color(bg_px[0 : 3], img.getpixel((right, y))[0 : 3]): right -= 1 break if x < w - 1: dest_x = (left + right) / 2 dest_y = y break
distance = abs(dest_x - base_x) print('dest:', dest_x, dest_y) x = (int)(random.random() * 200 + 600) y = (int)(random.random() * 200 + 600) # t 是长按的时间 t = distance * 600 / 383 loc = ' ' + str(x) + ' ' + str(y) + ' ' os.system('adb shell input swipe ' + loc + loc + str(t)) os.system('rm screenshot.png') time.sleep(3)